﻿using CHSystemApi.Framework.Base;
using CHSystemApi.Framework.Redis;
using CHSystemApi.DataAccess.DTO;
using CHSystemApi.DataAccess.Entities;
using CHSystemApi.Framework.DataAccess;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore;

namespace CHSystemApi.Business.implement
{
    public partial class UserBusiness : IUserBusiness
    {
        private IDataAccess _dataAccess { get; }

        private IRedis _redis { get; }

        private IConfiguration _configuration { get; }

        public UserBusiness(IDataAccess dataAccess, IRedis redis, IConfiguration configuration)
        {
            _dataAccess = dataAccess;
            _redis = redis;
            _configuration = configuration;
        }

        public string Login(LoginDtoIn dto)
        {
            User user = _dataAccess.Context.User.Where(x => x.id == 1).First();
            if (user is null) throw new Exception("用户不存在");
            if (MD5Hash.Hash.GetMD5(dto.password).ToUpper() != user.password) throw new Exception("密码错误");

            user.login_ip = dto.ip;
            user.last_login_time = DateTime.Now;
            _dataAccess.Context.User.Update(user);
            string token = CreateJwtPlayload(user, null);
            return token;
        }

        public bool Logout()
        {
            throw new NotImplementedException();
        }

        public RegisterDtoOut Register(RegisterDtoIn dto)
        {
            var cache = _redis.ChangeDataBase(Framework.Extension.RedisDataBaseType.Register).Get<Dictionary<string, string>>(dto.tel);

            if (string.IsNullOrEmpty(dto.vgid))
                throw new BaseException(Framework.Extension.StatusCode.OK, "环境异常，请重新获取验证码");

            if (string.IsNullOrEmpty(dto.vcode))
                throw new BaseException(Framework.Extension.StatusCode.OK, "验证码不能为空");

            if (string.IsNullOrEmpty(cache?["vcode"]))
                throw new BaseException(Framework.Extension.StatusCode.OK, "验证码已失效，请重新获取");

            if (cache?["vcode"].Equals(dto.vcode) == false)
                throw new BaseException(Framework.Extension.StatusCode.OK, "验证码错误");

            var user = new User()
            {
                create_time = DateTime.Now,
                password = MD5Hash.Hash.GetMD5(dto.password).ToUpper(),
                tel = dto.tel
            };
            if (_dataAccess.Context.User.Where(x => x.tel == user.tel).ToArray().Length == 0)
            {
                _redis.Remove(dto.tel);
                _dataAccess.Context.Add(user);
                _dataAccess.Context.SaveChanges();
                return new RegisterDtoOut() { id = user.id, age = user.age, last_login_time = user.last_login_time.ToString("G"), login_ip = user.login_ip, name = user.name };
            }
            else
                throw new BaseException(Framework.Extension.StatusCode.OK, "该手机号已经注册，请使用当前手机号登录");
        }

        public RegisterDtoIn SendCode(SendCodeDtoIn dto)
        {
            var usrs = _dataAccess.Context.User.Where(x => x.tel.Equals(dto.tel)).ToArray();

            if (usrs.Length == 0)
            {
                string vcode = "655896";
                string tel = dto.tel;
                string vgid = Guid.NewGuid().ToString();
                if (!string.IsNullOrEmpty(_redis.ChangeDataBase(Framework.Extension.RedisDataBaseType.Register).Get(dto.tel))) throw new Exception("当前手机号已发送验证码，60秒后重试！");
                if (_redis.Set(dto.tel, new
                {
                    vgid = vgid,
                    vcode = vcode
                }, new TimeSpan(0, 0, 60)))
                    return new RegisterDtoIn() { tel = tel, vgid = vgid };
            }
            throw new BaseException(Framework.Extension.StatusCode.OK, "该手机号已经注册，请使用当前手机号登录");
        }

        public UserDtoOut GetInfo(string name, string tel)
        {
            var data = _dataAccess.Context.User.Where(x => x.name == name && x.tel == tel).Select(x => new
            {
                x.name,
                x.age,
                x.tel,
                x.create_time,
                x.last_login_time,
                x.login_ip
            }).FirstOrDefault();
            return new UserDtoOut()
            {
                name = data.name,
                age = data.age,
                tel = data.tel,
                create_time = data.create_time,
                last_login_time = data.last_login_time,
                login_ip = data.login_ip
            };
        }
    }
}
